package com.example.intermingle.config;

import com.example.intermingle.service.UserService;
import com.example.intermingle.util.UserUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.*;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author 绿松石
 * @version V1.0
 * @Title SecurityConfig
 * @Description
 * @date 2021年08月19日 15:02
 * @since V1.0
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserService userService;

    @Autowired
    userEmpowerConfig userEmpowerConfig;

    @Autowired
    UserRoleStorageConfig userRoleStorageConfig;

    /**
     * 密码加密
     * @return
     */
    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

   /* @Bean
    SessionRegistryImpl sessionRegistry() {
        return new SessionRegistryImpl();
    }*/

    @Autowired
    AuthenticationAccessDeniedHandler authenticationAccessDeniedHandler;


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService);
    }



    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/swagger-ui.html",
                "/webjars/**",
                "/swagger-resources/**",
                "/v2/**");
    }
    @Override
    protected void configure ( HttpSecurity http ) throws Exception {
        http.authorizeRequests ().withObjectPostProcessor ( new ObjectPostProcessor<FilterSecurityInterceptor> () {
                    @Override
                    public <O extends FilterSecurityInterceptor> O postProcess ( O o ) {
                        o.setSecurityMetadataSource ( userRoleStorageConfig );
                        o.setAccessDecisionManager ( userEmpowerConfig );
                        return o;
                    }
                } ).and ().formLogin ().loginPage ( "/login_p" ).loginProcessingUrl ( "/login" )
                .usernameParameter ( "username" ).passwordParameter ( "password" ).permitAll ()
                .failureHandler ( new AuthenticationFailureHandler() {
                    @Override
                    public void onAuthenticationFailure ( HttpServletRequest httpServletRequest ,
                                                          HttpServletResponse httpServletResponse , AuthenticationException e )
                            throws IOException, ServletException {
                        httpServletResponse.setContentType ( "application/json;charset=utf-8" );
                        PrintWriter out = httpServletResponse.getWriter ();
                        StringBuffer sb = new StringBuffer ();
                        sb.append ( "{\"status\":\"error\",\"msg\":\"" );
                        if ( e instanceof UsernameNotFoundException || e instanceof BadCredentialsException ) {
                            sb.append ( "用户名或密码输入错误，登录失败!" );
                        }
                        else if ( e instanceof DisabledException ) {
                            sb.append ( "账户被禁用，登录失败，请联系管理员!" );
                        }
                        else {
                            sb.append ( "登录失败!" );
                        }
                        sb.append ( "\"}" );
                        out.write ( sb.toString () );
                     /* //设置返回信息
                    ResponseMsg<User> userResponseMsg=new ResponseMsg<>();
                    //设置状态码
                    userResponseMsg.setStatus(Constants.statusCode.STATUS_500);
                    //判断是什么类型的状态码，返回什么类型的提示语
                    if (e instanceof LockedException) {
                        userResponseMsg.setMsg(Constants.exception.USER_LockedException);
                    } else if (e instanceof CredentialsExpiredException) {
                        userResponseMsg.setMsg(Constants.exception.USER_CredentialsExpiredException);
                    } else if (e instanceof AccountExpiredException) {
                        userResponseMsg.setMsg(Constants.exception.USER_AccountExpiredException);
                    } else if (e instanceof DisabledException) {
                        userResponseMsg.setMsg(Constants.exception.USER_DisabledException);
                    } else if (e instanceof BadCredentialsException) {
                        userResponseMsg.setMsg(Constants.exception.USER_BadCredentialsException);
                    }
                        out.write (new ObjectMapper().writeValueAsString(userResponseMsg));*/
                        out.flush ();
                        out.close ();
                    }
                } ).successHandler ( new AuthenticationSuccessHandler() {
                    @Override
                    public void onAuthenticationSuccess (HttpServletRequest httpServletRequest ,
                                                         HttpServletResponse httpServletResponse , Authentication authentication )
                            throws IOException, ServletException {
                        httpServletResponse.setContentType ( "application/json;charset=utf-8" );
                        PrintWriter out = httpServletResponse.getWriter ();
                        ObjectMapper objectMapper = new ObjectMapper ();
                        String s = "{\"status\":\"success\",\"msg\":"
                                + objectMapper.writeValueAsString ( UserUtils.getCurrentHr () ) + "}";
                        out.write ( s );
                  /*      //获取用户信息
                    User user = (User) authentication.getPrincipal();
                    user.setUserPassword(null);
                        //设置返回信息
                    ResponseMsg<User> userResponseMsg=new ResponseMsg<>();
                    userResponseMsg.setMsg(Constants.SUCCESS_PROMPT_LANGUAGE);
                    userResponseMsg.setBody(user);
                    userResponseMsg.setStatus(Constants.statusCode.STATUS_200);
                        out.write (new ObjectMapper().writeValueAsString(userResponseMsg) );*/
                        out.flush ();
                        out.close ();
                    }
                } ).and ().logout ().permitAll ().and ().csrf ().disable ().exceptionHandling ()
                .accessDeniedHandler ( authenticationAccessDeniedHandler );
    }
//    @Override
//    protected void configure(HttpSecurity http) throws Exception {
//        http.authorizeRequests()
//                .antMatchers("/swagger-ui.html",
//                        "/webjars/**",
//                        "/swagger-resources/**",
//                        "/v2/**").permitAll()
//                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
//                    @Override
//                    public <O extends FilterSecurityInterceptor> O postProcess(O o) {
//                        o.setAccessDecisionManager(userEmpowerConfig);
//                        o.setSecurityMetadataSource(userRoleStorageConfig);
//                        return o;
//                    }
//                })
//                .and()
//                .logout()
//                .logoutSuccessHandler((req, resp, authentication) -> {
//                            resp.setContentType("application/json;charset=utf-8");
//                            PrintWriter out = resp.getWriter();
//                            ResponseMsg<User> userResponseMsg=new ResponseMsg<>();
//                            userResponseMsg.setMsg(Constants.LOGOUT_SUCCESS);
//                            out.write(new ObjectMapper().writeValueAsString(userResponseMsg));
//                            out.flush();
//                            out.close();
//                        }
//                )
//                .permitAll()
//                .and()
//                .csrf().disable().exceptionHandling()
//                //没有认证时，在这里处理结果，不要重定向
//                .authenticationEntryPoint((req, resp, authException) -> {
//                            resp.setContentType("application/json;charset=utf-8");
//                            resp.setStatus(401);
//                            PrintWriter out = resp.getWriter();
//                            ResponseMsg<User> userResponseMsg=new ResponseMsg<>();
//                            if (authException instanceof InsufficientAuthenticationException) {
//                                userResponseMsg.setMsg(Constants.exception.USER_InsufficientAuthenticationException);
//                            }
//                            out.write(new ObjectMapper().writeValueAsString(userResponseMsg));
//                            out.flush();
//                            out.close();
//                        }
//                );
//        http.addFilterAt(loginFilterConfig(), UsernamePasswordAuthenticationFilter.class);
//        }

    /**
     * 登陆控制器校验
     * @return
     * @throws Exception
     */
//    @Bean
//    LoginFilterConfig loginFilterConfig() throws Exception {
//        LoginFilterConfig loginFilterConfig = new LoginFilterConfig();
//        loginFilterConfig.setAuthenticationSuccessHandler((request, response, authentication) -> {
//                    response.setContentType("application/json;charset=utf-8");
//                    PrintWriter out = response.getWriter();
//                    //获取用户信息
//                    User user = (User) authentication.getPrincipal();
//                    user.setUserPassword(null);
//                    //设置返回信息
//                    ResponseMsg<User> userResponseMsg=new ResponseMsg<>();
//                    userResponseMsg.setMsg(Constants.SUCCESS_PROMPT_LANGUAGE);
//                    userResponseMsg.setBody(user);
//                    userResponseMsg.setStatus(Constants.statusCode.STATUS_200);
//                    //输出返回信息
//                    out.write(userResponseMsg.toString());
//                    out.flush();
//                    out.close();
//                }
//        );
//        loginFilterConfig.setAuthenticationFailureHandler((request, response, exception) -> {
//                    response.setContentType("application/json;charset=utf-8");
//                    //获取文本打印流
//                    PrintWriter out = response.getWriter();
//                    //设置返回信息
//                    ResponseMsg<User> userResponseMsg=new ResponseMsg<>();
//                    //设置状态码
//                    userResponseMsg.setStatus(Constants.statusCode.STATUS_500);
//                    //判断是什么类型的状态码，返回什么类型的提示语
//                    if (exception instanceof LockedException) {
//                        userResponseMsg.setMsg(Constants.exception.USER_LockedException);
//                    } else if (exception instanceof CredentialsExpiredException) {
//                        userResponseMsg.setMsg(Constants.exception.USER_CredentialsExpiredException);
//                    } else if (exception instanceof AccountExpiredException) {
//                        userResponseMsg.setMsg(Constants.exception.USER_AccountExpiredException);
//                    } else if (exception instanceof DisabledException) {
//                        userResponseMsg.setMsg(Constants.exception.USER_DisabledException);
//                    } else if (exception instanceof BadCredentialsException) {
//                        userResponseMsg.setMsg(Constants.exception.USER_BadCredentialsException);
//                    }
//                    //输出返回信息
//                    out.write(new ObjectMapper().writeValueAsString(userResponseMsg.toString()));
//                    //刷新流
//                    out.flush();
//                    //关闭流
//                    out.close();
//                }
//        );
//        //设置自定义过滤器
//        loginFilterConfig.setAuthenticationManager(authenticationManagerBean());
//        //设置返回url
//        loginFilterConfig.setFilterProcessesUrl("/doLogin");
//        //设置只能存在一个session
//        ConcurrentSessionControlAuthenticationStrategy sessionStrategy = new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry());
//        sessionStrategy.setMaximumSessions(1);
//        loginFilterConfig.setSessionAuthenticationStrategy(sessionStrategy);
//        //返回登陆过滤器信息
//        return loginFilterConfig;
//    }


}
